﻿Imports Castle.ActiveRecord
Imports Castle.ActiveRecord.Queries
Imports Castle.ActiveRecord.Framework
Imports NHibernate
Imports NHibernate.Criterion

Namespace Model
    ''' <summary>
    ''' Criado em 07/01/2013 14:00:00
    ''' </summary>
    ''' <remarks></remarks>
    <Serializable(), ActiveRecord("estoque", DynamicUpdate:=True)> _
    Public Class Estoque
        Inherits ActiveRecordBase(Of Model.Estoque)

        Private _cd_estoque As Integer
        Private _cd_produto As Integer
        Private _cd_estoque_local As Integer
        'Private _cd_estoque_tamanho As Integer
        'Private _cd_estoque_cor As Integer
        Private _quantidade As Decimal
        Private _reservado As Decimal
        Private _alterado As Date

        ' FK
        Private _EstoqueLocal As Model.EstoqueLocal
        Private _Produto As Model.Produto
        'tamaho
        'cor

        ' Campos das FKs
        Private _ProdutoNome As String
        Private _Local As String


        <PrimaryKey(PrimaryKeyType.Sequence, SequenceName:="estoque_cd_estoque_seq")>
        Public Property cd_estoque As Integer
            Get
                Return _cd_estoque
            End Get
            Set(ByVal value As Integer)
                _cd_estoque = value
            End Set
        End Property

        <BelongsTo("cd_estoque_local")> _
        Public Property EstoqueLocal As Model.EstoqueLocal
            Get
                Return _EstoqueLocal
            End Get
            Set(ByVal value As Model.EstoqueLocal)
                _EstoqueLocal = value
                If _EstoqueLocal IsNot Nothing Then
                    _Local = _EstoqueLocal.estoque_local_descricao
                End If
            End Set
        End Property

        Public ReadOnly Property Local() As String
            Get
                Return _Local
            End Get
        End Property

        <[Property]("cd_estoque_local", Update:=False, Insert:=False)> _
        Public Property cd_estoque_local() As Integer
            Get
                Return _cd_estoque_local
            End Get
            Set(ByVal value As Integer)
                _cd_estoque_local = value
            End Set
        End Property


        <BelongsTo("cd_produto")> _
        Public Property Produto As Model.Produto
            Get
                Return _Produto
            End Get
            Set(ByVal value As Model.Produto)
                _Produto = value
                ' Carrega a descrição do produto para a grade de pesquisa
                If _Produto IsNot Nothing Then
                    _ProdutoNome = _Produto.pr_nome
                End If
            End Set
        End Property

        Public Property ProdutoNome() As String
            Get
                Return _ProdutoNome
            End Get
            Set(ByVal value As String)
                _ProdutoNome = value
            End Set
        End Property

        <[Property]("cd_produto", Update:=False, Insert:=False)> _
        Public Property cd_produto() As Integer
            Get
                Return _cd_produto
            End Get
            Set(ByVal value As Integer)
                _cd_produto = value
            End Set
        End Property


        <[Property]("quantidade")> _
        Public Property quantidade As Decimal
            Get
                Return _quantidade
            End Get
            Set(ByVal value As Decimal)
                _quantidade = value
            End Set
        End Property

        <[Property]("reservado")> _
        Public Property reservado As Decimal
            Get
                Return _reservado
            End Get
            Set(ByVal value As Decimal)
                _reservado = value
            End Set
        End Property

        <[Property]("alterado")> _
        Public Property alterado As Date
            Get
                Return _alterado
            End Get
            Set(ByVal value As Date)
                _alterado = value
            End Set
        End Property

        ''' <summary>
        ''' Lista o estoque agrupando por produto
        ''' http://docs.castleproject.org/Active%20Record.Using%20HQL%20(Hibernate%20Query%20language).ashx
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks>Precisa retornar no tipo Model.Estoque</remarks>
        Public Function ListaEstoque() As IList(Of Model.Estoque)

            ' Tipado (SimpleQuery)
            'Dim hql As String = String.Format("SELECT e, SUM(e.quantidade), SUM(e.reservado) FROM Estoque AS e INNER JOIN e.Produto as p GROUP BY e.Produto")
            Dim hql As String = String.Format("FROM Estoque")
            Dim sq As Castle.ActiveRecord.Queries.SimpleQuery(Of Model.Estoque) = New Castle.ActiveRecord.Queries.SimpleQuery(Of Model.Estoque)(hql)
            Dim result As IList(Of Model.Estoque) = sq.Execute()
            Return result

            ' Lista generica (SimpleQuery)
            'Dim hql As String = String.Format("FROM Estoque")
            'Dim sq As Castle.ActiveRecord.Queries.SimpleQuery(Of IList) = New SimpleQuery(Of IList)(hql)
            'Dim result As IList() = sq.Execute()
            'Return result

            ' Em C# (SimpleQuery)
            'string hql = String.Format("FROM Contact c where State in (:states)");
            'SimpleQuery Contact q = new SimpleQuery<Contact>(hql);
            'q.SetParameterList("states", stateslist);
            'q.SetQueryRange(25);
            'Contact[] result = q.Execute();

            ' Via Criterion
            'Dim q As ICriterion() = {Expression.Eq("cd_produto", "1")}
            '' C#: Order[] sort = { Order.Asc("LastName") }
            '' VB: Dim sort As Order() = {Order.Asc("LastName")}
            'Dim s As Order() = {Order.Asc("cd_estoque")}
            ' Return Model.Estoque.FindAll(s, q)

            '' Via Detached
            'Dim Query As DetachedCriteria = DetachedCriteria.For(Of Model.Estoque)("estoque")

            '' Seta os parâmetros do filtro
            'Query.SetProjection(Projections.ProjectionList() _
            '                    .Add(Projections.Sum("quantidade"), "quantidade") _
            '                    .Add(Projections.Sum("reservado"), "reservado") _
            '                    .Add(Projections.GroupProperty("cd_produto"), "cd_produto"))


            '' Passa o filtro para o método de listagem
            'Return Model.Estoque.FindAll(Query)
        End Function

        ''' <summary>
        ''' Pesquisa de estoque por Nome de Produto
        ''' </summary>
        ''' <param name="Produto">Nome do Produto</param>
        ''' <returns>Lista de Estoques</returns>
        ''' <remarks></remarks>
        Public Function GetByProdutoNome(ByVal produto As String) As IList(Of Model.Estoque)
            Dim dc As DetachedCriteria = DetachedCriteria.For(Of Model.Estoque)("estoque")

            ' Implementar busca por código de fabricante, barras, grupos, marcas...

            ' Inner Join Estoque com Produto
            ' "Propriedade na classe atual", "Nome da classe relacionada"
            ' Ref: http://www.guj.com.br/java/245290-resolvido-inner-join-criteria
            dc.CreateCriteria("Produto", "Produto", SqlCommand.JoinType.InnerJoin) _
                .Add(Restrictions.Like("pr_nome", produto, MatchMode.Anywhere).IgnoreCase)

            Return Model.Estoque.FindAll(dc)

        End Function


        ''' <summary>
        ''' Lista de estoque por produto
        ''' </summary>
        ''' <param name="cd_produto">Código do produto</param>
        ''' <returns>Lista de estoque</returns>
        ''' <remarks></remarks>
        Public Function GetByProduto(ByVal cd_produto As Integer) As IList(Of Model.Estoque)
            Dim dc As DetachedCriteria = DetachedCriteria.For(Of Model.Estoque)("estoque")

            dc.Add(Restrictions.Eq("cd_produto", cd_produto))

            Return Model.Estoque.FindAll(dc)
        End Function


    End Class
End Namespace
